package com.pomelo.base.core.util;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.ObjectUtils;

import com.github.pagehelper.PageRowBounds;
import com.pomelo.base.core.bean.DbTypeEnum;
import com.pomelo.base.core.bean.TableMetaData;
import com.pomelo.base.core.config.PomeloTransactionStatus;
import com.pomelo.base.core.dao.DaoService;
import com.pomelo.base.core.dao.DatabaseEntity;
import com.pomelo.base.core.datasource.DynamicDataSourceContextHolder;

/**
 * 数据库操作工具类
 *
 * @author biankudingcha
 * @date: 2021-07-21
 * @since 0.5.0
 */
@Component public class DbUtil {

    /**
     * 日期格式化
     */
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    /**
     * 日期时间格式
     */
    public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 日期时间带毫秒格式
     */
    public static final DateTimeFormatter LONG_DATETIME_FORMATTER =
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    /**
     * 默认数据源名称
     */
    public static final String DEFAULT_DATASOURCE = "defaultDataSource";

    /**
     * 操作数据库service
     */
    public static DaoService daoSevice;

    /**
     * 获取操作数据库service
     *
     * @return 操作数据库service
     */
    public static DaoService getDaoSevice() {
        return daoSevice;
    }

    /**
     * 设置操作数据库service
     *
     * @param daoSevice 操作数据库service
     */
    @Autowired public void setDaoService(DaoService daoSevice) {
        DbUtil.daoSevice = daoSevice;
    }

    public DbUtil() {

    }

    /**
     * 获取事务管理器
     *
     * @return 事务管理器对象
     * @throws Exception
     */
    public static PlatformTransactionManager getPlatformTransactionManager() throws Exception {
        return daoSevice.getPlatformTransactionManager();
    }

    /**
     * 保存
     *
     * @param tableName 表
     * @param data      数据
     * @return WID
     * @throws Exception
     */
    public static String save(String tableName, Map<String, Object> data) throws Exception {
        return save(null, tableName, data);
    }

    /**
     * 保存
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param data         数据
     * @return WID
     * @throws Exception
     */
    public static String save(String dataSourceId, String tableName, Map<String, Object> data) throws Exception {
        if (tableName == null || data == null || data.isEmpty()) {
            return null;
        }
        handleNull(tableName, data);
        return daoSevice.save(dataSourceId, tableName, data);
    }

    /**
     * 更新
     *
     * @param tableName 表
     * @param data      数据
     * @return WID
     * @throws Exception
     */
    public static String update(String tableName, Map<String, Object> data) throws Exception {
        return update(null, tableName, data);
    }

    /**
     * 更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param data         数据
     * @return WID
     * @throws Exception
     */
    public static String update(String dataSourceId, String tableName, Map<String, Object> data) throws Exception {
        if (tableName == null || data == null || data.isEmpty()) {
            return null;
        }
        handleNull(tableName, data);
        return daoSevice.update(dataSourceId, tableName, data, null, null);
    }

    /**
     * 更新
     *
     * @param tableName 表
     * @param keyNames  主键
     * @param data      数据
     * @return WID
     * @throws Exception
     */
    public static String update(String tableName, String[] keyNames, Map<String, Object> data) throws Exception {
        return update(null, tableName, keyNames, data);
    }

    /**
     * 更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param keyNames     主键
     * @param data         数据
     * @return WID
     * @throws Exception
     */
    public static String update(String dataSourceId, String tableName, String[] keyNames, Map<String, Object> data)
        throws Exception {
        if (tableName == null || data == null || data.isEmpty()) {
            return null;
        }
        handleNull(tableName, data);
        return daoSevice.update(dataSourceId, tableName, keyNames, data, null, null);
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param tableName 表
     * @param data      数据
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String tableName, Map<String, Object> data) throws Exception {
        return saveOrUpdate(null, tableName, data);
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param tableName 表
     * @param entity    数据
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String tableName, DatabaseEntity entity) throws Exception {
        return saveOrUpdate(null, tableName, entity.toChangeDataMap());
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param data         数据
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String dataSourceId, String tableName, Map<String, Object> data)
        throws Exception {
        if (tableName == null || data == null || data.isEmpty()) {
            return null;
        }
        handleNull(tableName, data);
        Object wid = data.get("WID");
        if (ObjectUtils.isEmpty(wid)) {
            data.put("WID", getNewWid());
            return daoSevice.save(dataSourceId, tableName, data);
        } else {
            return daoSevice.update(dataSourceId, tableName, data, null, null);
        }
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param entity       数据
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String dataSourceId, String tableName, DatabaseEntity entity) throws Exception {
        return saveOrUpdate(dataSourceId, tableName, entity.toChangeDataMap());
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param tableName 表
     * @param data      数据
     * @param condition 条件
     * @param params    条件参数
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String tableName, Map<String, Object> data, String condition, Object[] params)
        throws Exception {
        return saveOrUpdate(null, tableName, data, condition, params);
    }

    /**
     * 保存或更新，根据WID是否有值判断保存还是更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param data         数据
     * @param condition    条件
     * @param params       条件参数
     * @return WID
     * @throws Exception
     */
    public static String saveOrUpdate(String dataSourceId, String tableName, Map<String, Object> data, String condition,
        Object[] params) throws Exception {
        if (tableName == null || data == null || data.isEmpty()) {
            return null;
        }
        handleNull(tableName, data);
        Object wid = data.get("WID");
        if (ObjectUtils.isEmpty(wid)) {
            data.put("WID", getNewWid());
            return daoSevice.save(dataSourceId, tableName, data);
        } else {
            return daoSevice.update(dataSourceId, tableName, data, condition, params);
        }
    }

    /**
     * 批量保存或更新，根据WID是否有值判断保存还是更新，集合中对象属性需要保持一致
     *
     * @param tableName 表
     * @param datas     数据
     * @param condition 条件
     * @param params    条件参数
     * @throws Exception
     */
    public static void saveOrUpdate(String tableName, List<Map<String, Object>> datas, String condition,
        Object[] params) throws Exception {
        saveOrUpdate(null, tableName, datas, condition, params);
    }

    /**
     * 批量保存或更新，根据WID是否有值判断保存还是更新，集合中对象属性需要保持一致
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param datas        数据
     * @param condition    条件
     * @param params       条件参数
     * @throws Exception
     */
    public static void saveOrUpdate(String dataSourceId, String tableName, List<Map<String, Object>> datas,
        String condition, Object[] params) throws Exception {
        if (tableName == null || datas == null || datas.isEmpty()) {
            return;
        }
        handleNull(tableName, datas);
        List<Map<String, Object>> saveList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> updateList = new ArrayList<Map<String, Object>>();
        for (Map<String, Object> data : datas) {
            Object wid = data.get("WID");
            if (ObjectUtils.isEmpty(wid)) {
                data.put("WID", getNewWid());
                saveList.add(data);
            } else {
                updateList.add(data);
            }
        }
        if (!saveList.isEmpty()) {
            daoSevice.save(dataSourceId, tableName, saveList);
        }
        if (!updateList.isEmpty()) {
            daoSevice.update(dataSourceId, tableName, updateList, condition, params);
        }
    }

    /**
     * 批量保存或更新，根据WID是否有值判断保存还是更新，集合中对象属性需要保持一致
     *
     * @param tableName 表
     * @param datas     数据
     * @throws Exception
     */
    public static void saveOrUpdate(String tableName, List<Map<String, Object>> datas) throws Exception {
        saveOrUpdate(null, tableName, datas);
    }

    /**
     * 批量保存或更新，根据WID是否有值判断保存还是更新，集合中对象属性需要保持一致
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param datas        数据
     * @throws Exception
     */
    public static void saveOrUpdate(String dataSourceId, String tableName, List<Map<String, Object>> datas)
        throws Exception {
        if (tableName == null || datas == null || datas.isEmpty()) {
            return;
        }
        handleNull(tableName, datas);
        List<Map<String, Object>> saveList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> updateList = new ArrayList<Map<String, Object>>();
        for (Map<String, Object> data : datas) {
            Object wid = data.get("WID");
            if (ObjectUtils.isEmpty(wid)) {
                data.put("WID", getNewWid());
                saveList.add(data);
            } else {
                updateList.add(data);
            }
        }
        if (!saveList.isEmpty()) {
            daoSevice.save(dataSourceId, tableName, saveList);
        }
        if (!updateList.isEmpty()) {
            daoSevice.update(dataSourceId, tableName, updateList, null, null);
        }
    }

    /**
     * 批量保存
     *
     * @param tableName 表
     * @param datas     数据
     * @throws Exception
     */
    public static void save(String tableName, List<Map<String, Object>> datas) throws Exception {
        save(null, tableName, datas);
    }

    /**
     * 批量保存
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param datas        数据
     * @throws Exception
     */
    public static void save(String dataSourceId, String tableName, List<Map<String, Object>> datas) throws Exception {
        if (tableName == null || datas == null || datas.isEmpty()) {
            return;
        }
        handleNull(tableName, datas);
        daoSevice.save(dataSourceId, tableName, datas);
    }

    /**
     * 批量更新
     *
     * @param tableName 表
     * @param datas     数据
     * @throws Exception
     */
    public static void update(String tableName, List<Map<String, Object>> datas) throws Exception {
        update(null, tableName, datas);
    }

    /**
     * 批量更新
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param datas        数据
     * @throws Exception
     */
    public static void update(String dataSourceId, String tableName, List<Map<String, Object>> datas) throws Exception {
        if (tableName == null || datas == null || datas.isEmpty()) {
            return;
        }
        handleNull(tableName, datas);
        daoSevice.update(dataSourceId, tableName, datas, null, null);
    }

    /**
     * 根据WID删除数据
     *
     * @param tableName 表
     * @param wid       WID
     * @return 删除的数量
     * @throws Exception
     */
    public static int deleteByWid(String tableName, String wid) throws Exception {
        return deleteByWid(null, tableName, wid);
    }

    /**
     * 根据WID删除数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param wid          WID
     * @return 删除的数量
     * @throws Exception
     */
    public static int deleteByWid(String dataSourceId, String tableName, String wid) throws Exception {
        return daoSevice.deleteByWid(dataSourceId, tableName, wid, null, null);
    }

    /**
     * 删除数据
     *
     * @param tableName 表
     * @param condition 条件
     * @param params    条件参数
     * @return 删除的数量
     * @throws Exception
     */
    public static int delete(String tableName, String condition, Object[] params) throws Exception {
        return delete(null, tableName, condition, params);
    }

    /**
     * 删除数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表
     * @param condition    条件
     * @param params       条件参数
     * @return 删除的数量
     * @throws Exception
     */
    public static int delete(String dataSourceId, String tableName, String condition, Object[] params)
        throws Exception {
        return daoSevice.delete(dataSourceId, tableName, condition, params);
    }

    /**
     * 执行SQL语句
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 执行的结果数量
     * @throws Exception
     */
    public static int execute(String sql, Object[] params) throws Exception {
        return execute(null, sql, params);
    }

    /**
     * 执行SQL语句
     *
     * @param sql          SQL
     * @return 执行的结果数量
     * @throws Exception
     */
    public static void execute(String sql) throws Exception {
        daoSevice.execute(null, sql);
    }

    /**
     * 执行SQL语句
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 执行的结果数量
     * @throws Exception
     */
    public static int execute(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.execute(dataSourceId, sql, params);
    }




    /**
     * 查询
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 查询的结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String sql, Object[] params) throws Exception {
        return query(null, sql, params);
    }

    /**
     * 查询
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 查询的结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.query(dataSourceId, sql, params);
    }

    /**
     * 分页查询
     *
     * @param sql    SQL
     * @param params SQL参数
     * @param page   分页信息
     * @param sort   排序字段，多个字段用逗号隔开
     * @return 查询的结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String sql, Object[] params, PageRowBounds page, String sort)
        throws Exception {
        return query(null, sql, params, page, sort);
    }

    /**
     * 分页查询
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @param page         分页信息
     * @param sort         排序字段，多个字段用逗号隔开
     * @return 查询的结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String dataSourceId, String sql, Object[] params, PageRowBounds page,
        String sort) throws Exception {
        return daoSevice.query(dataSourceId, sql, params, page, sort);
    }

    /**
     * 分页查询
     *
     * @param sql    SQL
     * @param params SQL参数
     * @param page   分页信息
     * @return 查询的结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String sql, Object[] params, PageRowBounds page) throws Exception {
        return query(null, sql, params, page);
    }

    /**
     * 分页查询
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @param page         分页信息
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> query(String dataSourceId, String sql, Object[] params, PageRowBounds page)
        throws Exception {
        return daoSevice.query(dataSourceId, sql, params, page);
    }

    /**
     * 查询一行数据
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 返回第一行数据
     * @throws Exception
     */
    public static Map<String, Object> queryRow(String sql, Object[] params) throws Exception {
        return queryRow(null, sql, params);
    }

    /**
     * 查询一行数据
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 返回第一行数据
     * @throws Exception
     */
    public static Map<String, Object> queryRow(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.queryRow(dataSourceId, sql, params);
    }

    /**
     * 查询第一行第一列数据
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 第一行第一列数据
     * @throws Exception
     */
    public static Object queryOne(String sql, Object[] params) throws Exception {
        return queryOne(null, sql, params);
    }

    /**
     * 查询第一行第一列数据
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 第一行第一列数据
     * @throws Exception
     */
    public static Object queryOne(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.queryOne(dataSourceId, sql, params);
    }

    /**
     * 查询第一列数据
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 第一列数据
     * @throws Exception
     */
    public static List<Object> queryOnes(String sql, Object[] params) throws Exception {
        return queryOnes(null, sql, params);
    }

    /**
     * 查询第一列数据
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 第一列数据
     * @throws Exception
     */
    public static List<Object> queryOnes(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.queryOnes(dataSourceId, sql, params);
    }

    /**
     * 查询数据转map格式，第一列做为键，第二列做为值
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return Map格式数据
     * @throws Exception
     */
    public static Map<String, Object> queryMap(String sql, Object[] params) throws Exception {
        return queryMap(null, sql, params);
    }

    /**
     * 查询数据转map格式，第一列做为键，第二列做为值
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return Map格式数据
     * @throws Exception
     */
    public static Map<String, Object> queryMap(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.queryMap(dataSourceId, sql, params);
    }

    /**
     * 查询结果转int
     *
     * @param sql    SQL
     * @param params SQL参数
     * @return 转为int的结果值
     * @throws Exception
     */
    public static int queryParseInt(String sql, Object[] params) throws Exception {
        return queryParseInt(null, sql, params);
    }

    /**
     * 查询结果转int
     *
     * @param dataSourceId 数据源
     * @param sql          SQL
     * @param params       SQL参数
     * @return 转为int的结果值
     * @throws Exception
     */
    public static int queryParseInt(String dataSourceId, String sql, Object[] params) throws Exception {
        return daoSevice.queryParseInt(dataSourceId, sql, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param tableName 表名称
     * @param condition 条件
     * @param params    参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String tableName, String condition, Object[] params)
        throws Exception {
        return queryTable(null, tableName, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param condition    条件
     * @param params       参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String dataSourceId, String tableName, String condition,
        Object[] params) throws Exception {
        return daoSevice.queryTable(dataSourceId, tableName, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param tableName 表名称
     * @param condition 条件
     * @param params    参数
     * @param sort      排序
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String tableName, String condition, Object[] params, String sort)
        throws Exception {
        return queryTable(null, tableName, condition, params, sort);
    }

    /**
     * 查询指定表的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param condition    条件
     * @param params       参数
     * @param sort         排序
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String dataSourceId, String tableName, String condition,
        Object[] params, String sort) throws Exception {
        return daoSevice.queryTable(dataSourceId, tableName, condition, params, sort);
    }

    /**
     * 查询指定表的数据
     *
     * @param tableName 表名称
     * @param wid       WID
     * @return 查询结果
     * @throws Exception
     */
    public static Map<String, Object> queryTableByWid(String tableName, String wid) throws Exception {
        return queryTableByWid(null, tableName, wid);
    }

    /**
     * 根据WID查询指定表的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param wid          WID
     * @return 查询结果
     * @throws Exception
     */
    public static Map<String, Object> queryTableByWid(String dataSourceId, String tableName, String wid)
        throws Exception {
        return daoSevice.queryTableByWid(dataSourceId, tableName, wid);
    }

    /**
     * 查询指定表第一行的数据
     *
     * @param tableName 表名称
     * @param condition 条件
     * @param params    参数
     * @return 查询结果
     * @throws Exception
     */
    public static Map<String, Object> queryTableRow(String tableName, String condition, Object[] params)
        throws Exception {
        return queryTableRow(null, tableName, condition, params);
    }

    /**
     * 查询指定表第一行的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param condition    条件
     * @param params       参数
     * @return 查询结果
     * @throws Exception
     */
    public static Map<String, Object> queryTableRow(String dataSourceId, String tableName, String condition,
        Object[] params) throws Exception {
        return daoSevice.queryTableRow(dataSourceId, tableName, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param tableName 表名称
     * @param page      分页信息
     * @param condition 条件
     * @param params    参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String tableName, PageRowBounds page, String condition,
        Object[] params) throws Exception {
        return queryTable(null, tableName, page, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param page         分页信息
     * @param condition    条件
     * @param params       参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String dataSourceId, String tableName, PageRowBounds page,
        String condition, Object[] params) throws Exception {
        return daoSevice.queryTable(dataSourceId, tableName, page, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param tableName 表名称
     * @param page      分页信息
     * @param ordery    排序字段
     * @param condition 条件
     * @param params    参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String tableName, PageRowBounds page, String ordery,
        String condition, Object[] params) throws Exception {
        return queryTable(null, tableName, page, ordery, condition, params);
    }

    /**
     * 查询指定表的数据
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param page         分页信息
     * @param ordery       排序字段
     * @param condition    条件
     * @param params       参数
     * @return 查询结果
     * @throws Exception
     */
    public static List<Map<String, Object>> queryTable(String dataSourceId, String tableName, PageRowBounds page,
        String ordery, String condition, Object[] params) throws Exception {
        return daoSevice.queryTable(dataSourceId, tableName, page, ordery, condition, params);
    }

    /**
     * 查询指定表的数据数量
     *
     * @param tableName 表名称
     * @param condition 条件
     * @param params    参数
     * @return 数量
     * @throws Exception
     */
    public static long queryTableCount(String tableName, String condition, Object[] params) throws Exception {
        return queryTableCount(null, tableName, condition, params);
    }

    /**
     * 查询指定表的数据数量
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @param condition    条件
     * @param params       参数
     * @return 数据
     * @throws Exception
     */
    public static long queryTableCount(String dataSourceId, String tableName, String condition, Object[] params)
        throws Exception {
        return daoSevice.queryTableCount(dataSourceId, tableName, condition, params);
    }

    /**
     * 获取WID
     *
     * @return GUID
     * @throws Exception
     */
    public static String getNewWid() throws Exception {
        return daoSevice.getNewWid();
    }

    /**
     * 获取表的元素信息
     *
     * @param tableName 表名称
     * @return 表的元素信息
     * @throws Exception
     */
    public static TableMetaData getTableMeta(String tableName) throws Exception {
        return getTableMeta(null, tableName);
    }

    /**
     * 获取表的元素信息
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @return 表信息
     * @throws Exception
     */
    public static TableMetaData getTableMeta(String dataSourceId, String tableName) throws Exception {
        return daoSevice.getTableMeta(dataSourceId, tableName);
    }

    /**
     * 获取数据库厂家
     *
     * @return 数据库厂商
     * @throws Exception
     */
    public static String getDatabaseProductName() throws Exception {
        return getDatabaseProductName(null);
    }

    /**
     * 获取数据库厂家
     *
     * @param dataSourceId 数据源
     * @return 数据库厂商
     * @throws Exception
     */
    public static String getDatabaseProductName(String dataSourceId) throws Exception {
        return daoSevice.getDatabaseProductName(dataSourceId);
    }

    /**
     * 获取数据库当前日期
     *
     * @return 当前日期字符串
     * @throws Exception
     */
    public static String getCurrentDateStr() throws Exception {
        return getCurrentDateTime().toLocalDateTime().format(DATE_FORMATTER);
    }

    /**
     * 获取数据库当前时间
     *
     * @return 当前日期时间字符串
     * @throws Exception
     */
    public static String getCurrentDateTimeStr() throws Exception {
        return getCurrentDateTime().toLocalDateTime().format(DATETIME_FORMATTER);
    }

    /**
     * 获取数据库当前时间字符串 yyyy-MM-dd HH:mm:ss.SSS
     *
     * @return 当前日期时间字符串
     * @throws Exception
     */
    public static String getCurrentLongDateTimeStr() throws Exception {
        return getCurrentDateTime().toLocalDateTime().format(LONG_DATETIME_FORMATTER);
    }

    /**
     * 获取当前时间
     *
     * @return 当前时间timestamp
     * @throws Exception
     */
    public static Timestamp getCurrentDateTime() throws Exception {
        String productname = getDatabaseProductName().toUpperCase();
        String sql = null;
        if (DbTypeEnum.ORACLE.toString().equalsIgnoreCase(productname)) {
            sql = "SELECT SYSTIMESTAMP FROM DUAL";
        } else if (DbTypeEnum.MYSQL.toString().equalsIgnoreCase(productname)) {
            sql = "SELECT NOW()";
        } else if (DbTypeEnum.H2.toString().equalsIgnoreCase(productname)) {
            sql = "SELECT CURRENT_TIMESTAMP()";
        }
        // 如果获取不到类型，则用oracle数据库
        if (ObjectUtils.isEmpty(sql)) {
            sql = "SELECT SYSTIMESTAMP FROM DUAL";
        }
        return daoSevice.getJdbcTemplate().query(sql, new ResultSetExtractor<Timestamp>() {
            @Override public Timestamp extractData(ResultSet rs) throws SQLException, DataAccessException {
                if (rs.next()) {
                    return rs.getTimestamp(1);
                }
                return null;
            }
        });
    }

    /**
     * 回滚事务
     *
     * @throws Exception
     */
    public static void rollbackOnly() throws Exception {
        Map<String, PomeloTransactionStatus> transactionStatusMap =
            DynamicDataSourceContextHolder.getTransactionStatus();
        if (transactionStatusMap != null && !transactionStatusMap.isEmpty()) {
            for (Iterator<Entry<String, PomeloTransactionStatus>> iter =
                 transactionStatusMap.entrySet().iterator(); iter.hasNext(); ) {
                Entry<String, PomeloTransactionStatus> entry = iter.next();
                daoSevice.rollback(entry.getValue());
            }
        }
        // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }

    /**
     * 处理空值
     *
     * @param tableName 表名称
     * @param datas     数据
     * @throws Exception
     */
    public static void handleNull(String tableName, List<Map<String, Object>> datas) throws Exception {
        if (datas == null || datas.isEmpty()) {
            return;
        }
        for (int i = 0, len = datas.size(); i < len; i++) {
            Map<String, Object> data = datas.get(i);
            handleNull(tableName, data);
        }
    }

    /**
     * 处理空值
     *
     * @param tableName 表名称
     * @param data      数据
     * @throws Exception
     */
    public static void handleNull(String tableName, Map<String, Object> data) throws Exception {
        if (data == null || data.isEmpty()) {
            return;
        }
        Iterator<Entry<String, Object>> iter = data.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<String, Object> entry = iter.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if (ObjectUtils.isEmpty(value)) {
                data.put(key, null);
            }
        }
    }

    /**
     * 获取事务状态
     *
     * @return PomeloTransactionStatus
     * @throws TransactionException
     */
    public static PomeloTransactionStatus getTransaction() throws TransactionException {
        return daoSevice.getTransaction(null, null);
    }

    /**
     * 获取事务状态
     *
     * @param dataSourceId 数据源
     * @param definition   事务
     * @return PomeloTransactionStatus
     * @throws TransactionException
     */
    public static PomeloTransactionStatus getTransaction(String dataSourceId, DefaultTransactionDefinition definition)
        throws TransactionException {
        return daoSevice.getTransaction(dataSourceId, definition);
    }

    /**
     * 提交事务
     *
     * @param status 事务状态
     * @throws TransactionException
     */
    public static void commit(PomeloTransactionStatus status) throws TransactionException {
        daoSevice.commit(status);
    }

    /**
     * 回滚事务
     *
     * @param status 事务状态
     * @throws TransactionException
     */
    public static void rollback(PomeloTransactionStatus status) throws TransactionException {
        daoSevice.rollback(status);
    }

    /**
     * 获取数据库所有的表
     *
     * @param dataSourceId 数据源
     * @return 表信息
     * @throws Exception
     */
    public static List<Map<String, Object>> getTables(String dataSourceId) throws Exception {
        return daoSevice.getTables(dataSourceId);
    }

    /**
     * 表是否存在
     *
     * @param dataSourceId 数据源
     * @param tableName    表名称
     * @return true/false
     * @throws Exception
     */
    public static boolean getTables(String dataSourceId, String tableName) throws Exception {
        return daoSevice.tableExists(dataSourceId, tableName);
    }

}
